package cn.tedu.icop.basic.startup;
import cn.tedu.icop.api.domain.StationVO;
import cn.tedu.icop.basic.dao.repository.StationRepository;
import cn.tedu.icop.basic.pojo.StationPO;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 缓存预热
 * 在项目启动的时候,
 * 从数据库查询查找信息到Redis
 * 场站的基本信息
 * 场站的位置信息
 */
@Slf4j
@Component
public class StationRunner implements ApplicationRunner {

    public static final String KEY_STATION_GEO = "stations_geo";
    private static final Object KEY_STATIONS_DETAIL = "stations_detail";
    @Autowired
    private StationRepository stationRepository;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        RLock lock=redissonClient.getLock("station_preheat_lock");
        boolean flag = lock.tryLock(3000, TimeUnit.SECONDS);
        if(flag) {
            log.debug("开始预热缓存...");
            //1.从mysql数据库加载场站信息
            List<StationPO> stationPOList = stationRepository.selectStationList();
            if (stationPOList == null) return;
            BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps(KEY_STATION_GEO);
            BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(KEY_STATIONS_DETAIL);
            //2.遍历场站信息,将信息放入到redis中
            for (StationPO stationPO : stationPOList) {
                log.debug("正在预热de 场站信息:{}", stationPO);
                //2.1将坐标信息放入到redis中
                //2.1.1 构建坐标对象
                double lng = Double.valueOf(stationPO.getStationLng().toString());
                double lat = Double.valueOf(stationPO.getStationLat().toString());
                Point point = new Point(lng, lat);
                //2.1.2 存储坐标对象
                boundGeoOperations.add(point, String.valueOf(stationPO.getId()));
                //2.2将场站详情信息存储到redis
                boundHashOperations.put(String.valueOf(stationPO.getId()), stationPO);
            }
            log.debug("所有场站信息预热完成");
        }

    }
}
